package com.example.controller;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

/*
 * @program: gateway-first-sight
 * @description: Gateway的demo
 * @author: ChenZhiXiang
 * @create: 2019-06-05 09:45
 */

@RestController
public class GatewayController {

    /** 在spring cloud gateway中使用RouteLocator的Bean进行路由转发，将请求进行处理，最后转发到目标的下游服务 */
    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(p -> p
                        .path("/get")
                        .filters(f -> f.addRequestHeader("Hello", "hello czx"))
                        .uri("http://httpbin.org:80/get"))
                .build();
    }

    /** 上面创建的route可以让请求“/get”请求都转发到“http://httpbin.org/get”。在route配置上，
     我们添加了一个filter，该filter会将请求添加一个header,key为hello，value为world。 */

    @Bean
    public RouteLocator myRoutes01(RouteLocatorBuilder builder){
        String httpUri = "http://httpbin.org:80";
        return builder.routes()
                .route(p -> p
                        .path("/hystrix")
                        .filters(f -> f.addRequestHeader("hello","hello czx"))
                        .uri(httpUri))
                .route(p -> p
                        .host("**.hystrix.com")
                        .filters(f -> f.hystrix(config -> config
                                        .setName("mycmd")
                                        .setFallbackUri("forward:/fallback")))
                .uri(httpUri))

                .build();
    }

    /** 我们使用了另外一个router，该router使用host去断言请求是否进入该路由，当请求的host有“*.hystrix.com”，都会进入该router，
     * 该router中有一个hystrix的filter,该filter可以配置名称、和指向性fallback的逻辑的地址，比如本案例中重定向到了“/fallback”。
      */

    @GetMapping("/fallback")
    public Mono<String> fallback() {
        return Mono.just("fallback");
    }
}
